home *** CD-ROM | disk | FTP | other *** search
- C VTAPEIN - READ LABELED TAPES WITH VERIABLE RECORD LENGTHS
- C
- C R. COUCH PRIME MARKETING SUPPORT N.Y.C. 03/28/85
- C
- C *** Reads tapes created by:
- C *** VAX with Unix using ANSITAR utility
- C *** VAX with VMS using the COPY utility
- C *** DECSYSTEM-20 using the WRITEL program
- C
- C *** These will come from VAX/VMSM, RSX-11 or RSTS/E sites
- C
- C *** This routine is written to read tapes written as follows:
- C
- C *** 9 Track, 1600 BPI
- C
- C *** ANSI labels (each label is an 80-byte ASCII record)
- C *** Each label begins with a 4-char identifier, like VOL1,HDR1,EOF.,EOV1
- C *** Volume name is in columns 5-10 (Vol labels only at beginning of tape)
- C *** HDR1 - file name is in columns 5-21
- C *** HDR2 - column 5 is record format (F, D, or S) (I only work with D)
- C *** 6-10 block length (I use what they tell me from keyboard)
- C *** 1-15 record length (this program defaults to 300
- C *** it doesn't matter anyway because
- C *** this is a max record size)
- C *** There may be an EOF1 and EOF2 they are skipped
- C *** At the end of the tape there is supposed to be an EOV1 and EOV2
- C *** followed by a double tape mark.
- C
- C *** Record Format "D":
- C *** Variable length records with a 4-digit ASCII length field at
- C *** the beginning of each record (the length includes the length field)
- C *** Line terminators are stripped, and there is no record crossing
- C *** a block boundry . The record may be padded at the end with 1, 2,
- C *** or 3 circumflex characters, which are not included in the field
- C *** length. (this programer did not know what the heck a circumflex
- C *** character was and did not take them into account. This routine
- C *** did however, work on the tape I had to test with.)
- C *** My spec called for block sizes of 2048, 4096, and 8192 characters
- C *** only, so this program only allows that selection. If there were
- C *** other block sizes to wory about simply allow that size to be entered.
- C
- C
- LOGICAL
- * OPEN$A,YSNO$A,CSTR$A,LSTR$A
- C
- C
- INTEGER
- * IUNIT,HRSIZE,READRC,STATUS(6),CODE,HAT,PUNIT,GCHR$A,
- * ZERO,GSTAT,TSTAT(6),TCODE,IBUF(4200),TCHAR,RLEN,MAXCHR,
- * I,J,K,L,OCTAL,TEXT,LSIZ(2),LBUF(150),EARY(152),FIXODD,
- * ESIZ,BUFPNT,RSIZ, DATASZ,FSTCHR,LSTCHR,FNAM(8),EOF,
- * NUNAM(9),NLEN,NLEN$A,RWIND,XCODE,GTPMRK,WDATSZ,JOBNO,
- * TSTNAM(8),TSTLEN,CKLEN,SKPREC
- C
- C
- INTEGER*4
- * BIGZRO
- C
- C
- EQUIVALENCE
- * (EARY(1),LSIZ(1)),
- * (EARY(3),LBUF(1)),
- * (IBUF(2),NUNAM(1)),
- * (IBUF(3),FNAM(1))
- C
- C
- $INSERT SYSCOM>A$KEYS
- $INSERT SYSCOM>ERRD.INS.FTN
- C
- C
- HRSIZE = 40 /* HEADER RECORD SIZE
- READRC = :042600 /* READ A RECORD (BLOCK)
- RWIND = :000040 /* REWIND TAPE
- GSTAT = :100000 /* GET TAPE STATUS (CAUSES A WAIT ON SEMIPHORE)
- GTPMRK = :022200 /* GET TAPE MARK
- SKPREC = :062200
- ZERO = 0
- BIGZRO = 0
- OCTAL = 7777
- TEXT = 0000
- HAT = '^ '
- EOF = 0
- C
- 5 CONTINUE
- CALL TONL
- CALL TNOUA ('ENTER TAPE DRIVE #: ',20)
- READ (1,10,ERR=5) IUNIT
- 10 FORMAT (I2)
- 15 CONTINUE
- CALL TNOUA ('BLOCK SIZE (2048,4096 OR 8192 ONLY): ',37)
- READ (1,20,ERR=15) DATASZ
- 20 FORMAT (I4)
- WDATSZ = DATASZ / 2
- IF (DATASZ.NE.2048 .AND.
- * DATASZ.NE.4096 .AND.
- * DATASZ.NE.8192) GOTO 15
- C
- C *** REWIND TO BEGINNING OF TAPE
- C *** READ THE VOLUME LABEL
- C
- CALL T$MT (IUNIT,BIGZRO,ZERO,RWIND,TSTAT,TCODE)
- C
- C *** DURING REWIND LET'S SEE WHAT HE WANT'S TO DO
- C
- 70 CONTINUE
- JOBNO = 0 /* READ ALL FILES
- IF (YSNO$A('READ FULL TAPE ',15,A$NDEF)) GO TO 90
- JOBNO = 1 /* READ A SINGLE FILE
- IF (YSNO$A('READ A SINGLE FILE ',19,A$NDEF)) GOTO 80
- JOBNO = 2 /* READ ALL FILES CONTAINING STRING
- IF (YSNO$A('READ ALL FILES CONTAINING STRING ',33,A$NDEF))
- * GOTO 80
- GOTO 70
- 80 CONTINUE
- CALL TNOUA ('ENTER FULL NAME OR STRING (16 CHAR MAX): ',41)
- READ (1,85) TSTNAM
- 85 FORMAT (8A2)
- TSTLEN = NLEN$A (TSTNAM,16)
- IF (TSTLEN.EQ.0) GOTO 80
- 90 CONTINUE
- CALL T$MT (IUNIT,BIGZRO,ZERO,GSTAT,TSTAT,XCODE)
- IF (TCODE.NE.0) GOTO 9020
- CALL T$MT (IUNIT,LOC(IBUF),HRSIZE,READRC,STATUS,CODE) /* VOLUME HEADER
- CALL T$MT (IUNIT,BIGZRO,ZERO,GSTAT,TSTAT,TCODE)
- C
- C *** READ THE HDR1 RECORD , TURN ON THE :200 BIT IN EACH CHARACTER
- C *** GET THE FILE NAME OUT OF COLUMNS 5-21, AND OPEN A SAM FILE OF
- C *** THAT NAME FOR WRITTING. (ON THE TAPE THAT I HAD SOME OF THE FILE
- C *** NAMES BEGAN WITH DIGITS, SO I INSERTED 'V.' IN FRONT OF THE NAME)
- C
- 100 CONTINUE
- CALL T$MT (IUNIT,LOC(IBUF),HRSIZE,READRC,STATUS,CODE) /* HEADER
- CALL T$MT (IUNIT,BIGZRO,ZERO,GSTAT,TSTAT,TCODE)
- IF (AND(STATUS(2),:400).NE.0) GOTO 9500 /* MUST BE END OF VOLUME
- DO 1055 I = 1,50
- IBUF(I) = OR(IBUF(I),:100200)
- 1055 CONTINUE
- NUNAM(1) = 'V.'
- NLEN = NLEN$A(NUNAM,18)
- CKLEN = NLEN - 2
- CALL TNOU (FNAM,CKLEN)
- IF (JOBNO.EQ.0) GOTO 104 /* READ ALL FILES
- IF (JOBNO.NE.1) GOTO 103
- IF (CSTR$A(TSTNAM,TSTLEN,FNAM,CKLEN)) GOTO 104
- GOTO 375
- 103 CONTINUE
- IF (LSTR$A(TSTNAM,TSTLEN,FNAM,CKLEN,FSTCHR,LSTCHR))
- * GOTO 104
- GO TO 375
- 104 CONTINUE
- CALL TNOUA ('OPENING ',8)
- CALL TNOU (NUNAM,NLEN)
- IF (OPEN$A(A$WRIT+A$SAMF+A$GETU,NUNAM,NLEN,PUNIT)) GOTO 105
- CALL TNOUA ('CAN''T OPEN ',11)
- GOTO 9000
- 105 CONTINUE
- C
- C *** DON'T CARE ABOUT BALANCE OF HEADER STUFF, SO SKIP TO NEXT TAPE
- C *** THIS IS THE ACTUAL DATA STUFF
- C
- 110 CONTINUE
- CALL T$MT (IUNIT,BIGZRO,ZERO,GTPMRK,TSTAT,XCODE)
- C
- C *** READ A BLOCK OF THE ACTUAL TAPE DATA, TURN ON THE :200 BIT
- C *** IN EACH CHARACTER
- C
- 200 CONTINUE
- CALL T$MT (IUNIT,LOC(IBUF),WDATSZ,READRC,STATUS,CODE)
- CALL T$MT (IUNIT,BIGZRO,ZERO,GSTAT,TSTAT,TCODE)
- IF (STATUS(3).EQ.0) GOTO 300
- MAXCHR = STATUS(3) * 2 - 1
- DO 205 I = 1,WDATSZ
- IBUF(I) = OR(IBUF(I),:100200)
- 205 CONTINUE
- BUFPNT = 0
- FSTCHR = 1
- LSTCHR = 4
- C
- C *** FIRST 4 CHAR OF EACH DATA RECORD AR THE RECORD LENGTH
- C *** IN CHARACTERS (THIS INCLUDES THE 4 CHAR).
- C *** MOVE THE RECORD OUT OF THE TAPE BUFFER INTO A LINE BUFFER
- C *** STUFF A SPACE AT THE END TO TAKE CARE OF ODD CHAR LENGTH RECORDS
- C *** WRITE IT TO THE DISK FILE, BUMP THE TAPE BUFFER POINTERS
- C *** IF LAST CHARA POINTER IS POINTING BEYOND NUMBER OF WORDS
- C *** READ IN THIS BLOCK WE ARE READY TO GET THE NEXT BLOCK
- C
- 210 CONTINUE
- CALL MSUB$A (IBUF,DATASZ,FSTCHR,LSTCHR,LSIZ,4,1,4)
- DECODE (4,225,LSIZ,ERR=400) ESIZ
- 225 FORMAT (I4)
- IF (ESIZ.GT.304) GOTO 5000 /* LINE IS OUT OF RANGE
- LSTCHR = FSTCHR + ESIZ - 1
- CALL MSUB$A (IBUF,DATASZ,FSTCHR,LSTCHR,EARY,304,1,ESIZ)
- RSIZ = ESIZ - 4
- RLEN = (RSIZ + 1) / 2
- FIXODD = RSIZ + 1
- CALL MCHR$A (LBUF,FIXODD,' ',1)
- CALL WTLIN$ (PUNIT,LBUF,RLEN,CODE)
- IF (CODE.NE.0) GOTO 9010
- FSTCHR = FSTCHR + ESIZ
- LSTCHR = FSTCHR + 3
- IF (LSTCHR.GE.MAXCHR) GOTO 300
- GOTO 210
- C *** THE TAPE BUFFER IS NOW EMPTY, IF WE HAVEN'T READ A TAPE MARK
- C *** GO GET THE NEXT DATA BLOCK.
- C *** IF WE HAVE READ A TAPE MARK IT'S END OF FILE, SKIP THE END
- C *** FILE LABEL AND GO GET THE NEXT FILE
- C
- 300 CONTINUE
- IF (AND(STATUS(2),:400).EQ.0) GOTO 200
- 325 CONTINUE
- CALL CLOS$A (PUNIT)
- IF (JOBNO.EQ.1) GOTO 9510
- C
- C *** WE GO FORWARD ONE TAPE MARK HERE.
- C *** FRANKLY, I DON'T KNOW IF I'M SKIPPING THE TAPE MARK I READ
- C *** WHEN I TRIED TO GET THE NEXT DATA BLOCK OR IF I'M SKIPPING THE
- C *** THE 'EOF' RECORD, BUT IT SEEMS TO WORK.
- C
- 350 CONTINUE /* COME DIRECTLY HERE TO SKIP AN EOF RECORD
- CALL T$MT (IUNIT,BIGZRO,ZERO,GTPMRK,STATUS,CODE)
- CALL T$MT (IUNIT,BIGZRO,ZERO,GSTAT,TSTAT,XCODE)
- GOTO 100
- 375 CONTINUE /* COME DIRECTLY HERE TO SKIP A FILE
- C *** SKIP HEADER TAPE MARK
- CALL T$MT (IUNIT,BIGZRO,ZERO,GTPMRK,STATUS,CODE) /* HEADER
- CALL T$MT (IUNIT,BIGZRO,ZERO,GSTAT,TSTAT,XCODE)
- CALL T$MT (IUNIT,BIGZRO,ZERO,GTPMRK,STATUS,CODE) /* DATA FILE
- CALL T$MT (IUNIT,BIGZRO,ZERO,GSTAT,TSTAT,XCODE)
- GOTO 350 /* GO SKIP THE TRAILER LABEL
- C
- 400 CONTINUE
- WRITE (1,405) FSTCHR,MAXCHR
- 405 FORMAT ('POINTING AT CHAR#',I5,' READ',I5,' CHARS',/,
- * 'IF TAPE MARK GET NEXT FILE ELSE NEXT BLOCK')
- IF (AND(STATUS(2),:400).NE.0) GOTO 325
- GOTO 200
- C
- C
- 5000 CONTINUE
- WRITE (1,5005) ESIZ
- 5005 FORMAT ('THAT''S STUPID RECORD SIZE CAN''T BE ',I5)
- STOP 200
- C
- C
- 9000 CONTINUE
- CALL EXIT
- C
- 9010 CONTINUE
- WRITE (1,9015) CODE
- 9015 FORMAT ('ERROR',I6,' WRITTING DATA FILE')
- GOTO 9000
- 9020 CONTINUE
- IF (TCODE.NE.E$NASS) GOTO 9030
- CALL TNOU ('** TAPE NOT ASSIGNED **',23)
- CALL EXIT
- 9030 CONTINUE
- IF (TCODE.NE.E$BNWD) GOTO 9040
- CALL TNOU ('** BAD BLOCK SIZE **',20)
- CALL EXIT
- 9040 CONTINUE
- WRITE (1,9045) TCODE
- 9045 FORMAT ('TAPE ERROR -',I5)
- CALL EXIT
- 9500 CONTINUE
- CALL CLOS$A (PUNIT)
- CALL TONL
- CALL TNOU (' *** END OF TAPE ***',25)
- CALL EXIT
- 9510 CONTINUE
- CALL TNOU ('FILE COMPLETE',13)
- CALL EXIT
- END
-